home *** CD-ROM | disk | FTP | other *** search
- /* Assertion handling and recovery library. Inspired by the language
- Eiffel, by Bertrand Meyer (see the book by him for details). There are
- currently (91/05/25) 3 types of assertion macros: "require", used
- for preconditions; "ensure"; used for postconditions; and "check",
- used for assertions anywhere in the middle of a function. These macros
- can be used in the exact same way as the ANSI standard "assert" macro.
- See the header file for more specific details.
-
- Assertions can be disabled during compilation by defining the ANSI
- standard flag "NDEBUG". Any one of the 3 assertion macros can be
- enabled by defining a corresponding preprocessor flag. If
- assertions are compiled with the code they can be disabled at
- run-time using the appropriately named global variables. You
- can print a trace of all assertions called by compiling with
- ASSERT_TRACE and setting the trace flag in the assert options
- global variable.
-
- The default action when an assertion fails depends on the release level
- (see intialization of _assert structure below). An assertion may trigger
- an exception when it fails. By triggering an exception, assertions can
- be treated in a manner similar to any other error, resulting in at least
- somewhat failure tolerant code. By setting the options correctly, you
- can also allow the application to continue, which may be useful during
- debugging, since it allows you to examine the conditions in the routine
- that caused the assertion to fail.
-
- Compiling with assertions can greatly increase the number of
- strings in the program. In THINK C, it may be necessary to use the
- far data option. If this still results in more strings than
- acceptable, you can define ASSERT_COMPACT which prevents display
- of the condition string.
-
- Revision History:
-
- 94/01/20 aih
- - updated a few comments
-
- 94/01/06 aih
- - uses debug library to print error messages
-
- 93/12/15 aih
- - added ASSERT_COMPACT and ASSERT_FNAME to save string space
-
- 93/10/26 aih
- - the number of assertion options was getting large so i put them
- all into a global structure
- - added an option to print the stack frame on failure (not implemented yet)
-
- 93/10/18 aih
- - updated and added some comments from an older version of this library
- - added exception generation on assertion failure
-
- 93/03/15 aih
- - simplified library
-
- 93/03/12 AIH
- - System error alert isn't displayed since that caused a crash sometimes
-
- 91/06/13 AIH
- - Fixed a grammatical mistake in the comments and added a few comments
-
- 91/05/25 AIH
- - Fixed a few mistakes in the comments and added a few comments
-
- 91/05/12 AIH
- - Assertions are also echoed to a file
-
- 91/05/06 AIH
- - Added ability to do a long jump after an assertion is violated
-
- 91/04/20 AIH
- - The trailing newline is removed when DebugStr is called
-
- 91/03/18 AIH
- - Added separate compile-time and run-time flags for disabling
- each level of assertions.
- - Added some comments
- - Made error string static so it won't use much stack space
-
- 91/01/11 AIH
- - Merged AssertLibA4 into this file
-
- 91/01/05 Ari Halberstadt (AIH)
- - Inserted this standard header in all files */
-
- #ifndef NDEBUG
-
- #include <string.h>
- #include <stdio.h>
- #include "pstr.h"
- #include "AssertLib.h"
- #include "DebugLib.h"
- #include "ExceptionLib.h"
- #include "MacLib.h"
-
- struct _assert_options _assert = {
- RELEASE_LEVEL != RELEASE_FINAL, /* require */
- RELEASE_LEVEL != RELEASE_FINAL, /* ensure */
- RELEASE_LEVEL != RELEASE_FINAL, /* check */
- RELEASE_LEVEL == RELEASE_DEV, /* debug */
- RELEASE_LEVEL != RELEASE_DEV, /* raise */
- false, /* print */
- false, /* stack */
- false, /* trace */
- };
-
- static const char *what[ASSERT_LAST_KIND] = { "Require", "Ensure", "Check" };
-
- /* function called to trace an assertion */
- int _assert_trace(int type, const char *expr, const char *file, long line)
- {
- if (expr)
- DebugPrintf("%s: %s, file %s, line %ld\n", what[type], expr, file, line);
- else
- DebugPrintf("%s: file %s, line %ld\n", what[type], file, line);
- }
-
- /* function called when an assertion fails */
- int _assert_failed(int type, const char *expr, const char *file, long line)
- {
- CStr255 msg;
- Str255 pmsg;
-
- /* program_note: _assert.stack not implemented yet */
- if (expr)
- sprintf(msg, "%s failed: %s, file %s, line %ld", what[type], expr, file, line);
- else
- sprintf(msg, "%s failed: file %s, line %ld", what[type], file, line);
- if (_assert.debug && MacHasDebugger())
- DebugStr(c2pstrcpy(pmsg, msg));
- if (_assert.print)
- DebugPrintf("%s\n", msg);
- if (_assert.raise) {
- FailExplanationSet(msg);
- RAISE;
- }
- return(0);
- }
-
- #endif /* NDEBUG */
-